// ==========================================================================
// Copyright (C) 2018 - 2021 Beijing 51WORLD Digital Twin Technology Co., Ltd. 
// , and/or its licensors.  All rights reserved.
//
// The coded instructions, statements, computer programs, and/or related 
// material (collectively the "Data") in these files contain unpublished
// information proprietary to Beijing 51WORLD Digital Twin Technology Co., Ltd. 
// ("51WORLD") and/or its licensors,  which is protected by the People's 
// Republic of China and/or other countries copyright law and by 
// international treaties.
//
// The Data may not be disclosed or distributed to third parties or be
// copied or duplicated, in whole or in part, without the prior written
// consent of 51WORLD.
//
// The copyright notices in the Software and this entire statement,
// including the above license grant, this restriction and the following
// disclaimer, must be included in all copies of the Software, in whole
// or in part, and all derivative works of the Software, unless such copies
// or derivative works are solely in the form of machine-executable object
// code generated by a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
// 51WORLD DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
// OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. IN NO
// EVENT WILL 51WORLD AND/OR ITS LICENSORS BE LIABLE FOR ANY LOST
// REVENUES, DATA, OR PROFITS, OR SPECIAL, DIRECT, INDIRECT, OR
// CONSEQUENTIAL DAMAGES, EVEN IF 51WORLD AND/OR ITS LICENSORS HAS
// BEEN ADVISED OF THE POSSIBILITY OR PROBABILITY OF SUCH DAMAGES.
// ==========================================================================
#pragma once
#include <vector>
#include <map>
#ifndef WITHOUT_HDMAP
#include "SSD/SimVector.h"
#endif
#include <time.h>
#pragma pack(push) 
#pragma pack(1)

struct SimOne_Data
{
	long long timestamp = 0; // timestamp millisecond
	int frame = 0;
	int version = 0; // API version
};
struct SimOne_Data_Vec3f
{
	float x;
	float y;
	float z;
};
// ----------------------------
// SimOne Map (SimOne Output) 
// ----------------------------
#define SOSM_CASE_START_EVENT_LABEL "SOSM_CASE_EVENT_START"
#define SOSM_CASE_STOP_EVENT_LABEL "SOSM_CASE_EVENT_STOP"

#define SOSM_MAP_LABEL "SOSM_MAP"
#define SOSM_MAP_OD_LENGT 128
#define SOSM_MAP_ODURL_LENGT 256
#define SOSM_MAP_ODMD5_LENGT 128

#define SOSM_CASENAME_LENGTH 256
#define SOSM_CASEID_LENGT 256
#define SOSM_TASKID_LENGT 256
struct SimOne_Data_Map
{
	char openDrive[SOSM_MAP_OD_LENGT];
	char openDriveUrl[SOSM_MAP_ODURL_LENGT];
	char opendriveMd5[SOSM_MAP_ODMD5_LENGT];
};
// ----------------------------
// SimOne MainVehicle WayPoints (SimOne Output) 
// ----------------------------
#define SOSM_WAYPOINTS_LABEL "SOSM_WAYPOINTS"
#define SOSM_WAYPOINTS_SIZE_MAX 100
#define MAX_MAINVEHICLE_NAME_LEN 64
struct SimOne_Data_WayPoints_Entry
{
	int index;
	float posX; // MainVehicle WayPoints X on Opendrive (by meter)
	float posY; // MainVehicle WayPoints Y on Opendrive (by meter)

	float heading_x; // MainVehicle WayPoints heading orientation x in quaternion
	float heading_y; // MainVehicle WayPoints heading orientation y in quaternion
	float heading_z; // MainVehicle WayPoints heading orientation z in quaternion
	float heading_w; // MainVehicle WayPoints heading orientation w in quaternion
};

struct SimOne_Data_WayPoints :public SimOne_Data
{
	char mainVehicleId[MAX_MAINVEHICLE_NAME_LEN];
	int wayPointsSize; // MainVehicle WayPoints size
	SimOne_Data_WayPoints_Entry wayPoints[SOSM_WAYPOINTS_SIZE_MAX]; // WayPoints, 100 max
};
// ----------------------------
// Vehicle pose control data (SimOne Input) 
// ----------------------------
#define SOSM_POSE_CONTROL_PREFIX "SOSM_POSE_CONTROL_"
struct SimOne_Data_Pose_Control : public SimOne_Data
{
	float posX; // Position X on Opendrive (by meter)
	float posY; // Position Y on Opendrive (by meter)
	float posZ; // Position Z on Opendrive (by meter)
	float oriX; // Rotation X on Opendrive (by radian)
	float oriY; // Rotation Y on Opendrive (by radian)
	float oriZ; // Rotation Z on Opendrive (by radian)
	bool autoZ = false;// Automatically set Z according to scene
};

// ----------------------------
// Vehicle control data (SimOne Input)
// ----------------------------
#define SOSM_CONTROL_PREFIX "SOSM_CONTROL_"

// Vehicle control data (SimOne Input)
// ----------------------------
#define SOSM_DRIVER_CONTROL_PREFIX "SOSM_DRIVER_CONTROL_"

enum ESimOne_Gear_Mode
{
	ESimOne_Gear_Mode_Neutral = 0,
	ESimOne_Gear_Mode_Drive = 1,      // forward gear for automatic gear
	ESimOne_Gear_Mode_Reverse = 2,
	ESimOne_Gear_Mode_Parking = 3,

	ESimOne_Gear_Mode_1 = 4,    // forward gear 1 for manual gear
	ESimOne_Gear_Mode_2 = 5,
	ESimOne_Gear_Mode_3 = 6,
	ESimOne_Gear_Mode_4 = 7,
	ESimOne_Gear_Mode_5 = 8,
	ESimOne_Gear_Mode_6 = 9,
	ESimOne_Gear_Mode_7 = 10,
	ESimOne_Gear_Mode_8 = 11
};

enum ESimOne_Throttle_Mode
{
	ESimOne_Throttle_Mode_Percent = 0,         //[0, 1]                                                            
	ESimOne_Throttle_Mode_Torque = 1,          //engine torque, N.m                                                
	ESimOne_Throttle_Mode_Speed = 2,           //vehicle speed, m/s,   in this mode, brake input is ignored        
	ESimOne_Throttle_Mode_Accel = 3,           //vehicle acceleration, m/s^2, in this mode, brake input is ignored 
	ESimOne_Throttle_Mode_EngineAV = 4,        //engine, rpm                                                       
	ESimOne_Throttle_Mode_WheelTorque = 5     //torques applied to each wheel, array, size is the wheel number, N.m
};

enum ESimOne_Brake_Mode
{
	ESimOne_Brake_Mode_Percent = 0,                 // [0, 1], factor of max brake pressure
	ESimOne_Brake_Mode_MasterCylinderPressure = 1,  // MPa
	ESimOne_Brake_Mode_PedalForce = 2,              // N
	ESimOne_Brake_Mode_WheelCylinderPressure = 3,   // Mpa for each wheel
	ESimOne_Brake_Mode_WheelTorque = 4              // Nm for each wheel
};
enum ESimOne_Steering_Mode
{
	ESimOne_Steering_Mode_Percent = 0,            // [-1, 1], left turn is negative, right is positive
	ESimOne_Steering_Mode_SteeringWheelAngle = 1, // steering wheel angle, degree
	ESimOne_Steering_Mode_Torque = 2,             // torque to steering wheel, N.m
	ESimOne_Steering_Mode_AngularSpeed = 3,       // steering wheel angualr speed, degree/s
	ESimOne_Steering_Mode_WheelAngle = 4,         // degree for each wheel
	ESimOne_Steering_Mode_WheelAnglarSpeed = 5,   // degree/s for each wheel
};
enum ESimOne_LogLevel_Type
{
	ESimOne_LogLevel_Type_Debug = 0,
	ESimOne_LogLevel_Type_Information = 1,
	ESimOne_LogLevel_Type_Warning = 2,
	ESimOne_LogLevel_Type_Error = 3,
	ESimOne_LogLevel_Type_Fatal = 4
};

#define SO_MAX_WHEEL_NUM  20
struct SimOne_Data_Control : public SimOne_Data
{
	ESimOne_Throttle_Mode throttleMode = ESimOne_Throttle_Mode_Percent;
	float throttle;
	ESimOne_Brake_Mode brakeMode = ESimOne_Brake_Mode_Percent;
	float brake;
	ESimOne_Steering_Mode steeringMode = ESimOne_Steering_Mode_Percent;
	float steering;
	bool handbrake = false;
	bool isManualGear = false;
	// gear location
	ESimOne_Gear_Mode  gear;

	float clutch;

	// array data for throttle input when throttle mode is EThrottleMode_WheelTorque
	// the data sequence is: L1 (left wheel of alxe 1), R1 (right wheel of alxe 1),
	//                       L2, R2, L3, R3...
	float throttle_input_data[SO_MAX_WHEEL_NUM];
	// array data for brake input when throttle mode is EBrakeMode_WheelCylinderPressure or
	// EBrakeMode_WheelTorque
	float brake_input_data[SO_MAX_WHEEL_NUM];
	// array data for steering input when throttle mode is ESteeringMode_WheelAngle,
	// ESteeringMode_WheelAnglarSpeed
	float steering_input_data[SO_MAX_WHEEL_NUM];
};

struct SimOne_Trajectory_Point
{
	float posx;          // position x
	float posy;          // position y
	float speed;         // m/s
	float accel;         // accelelation m/s^2
	float theta;         // yaw   rad
	float kappa;         // curvature
	float relative_time; // time relative to the first trajectory point
	float s;             // distance from the first trajectory point
};

#define SO_MAX_TRAJECTORY_POINT_NUM 500
struct SimOne_Data_Control_Trajectory : public SimOne_Data
{
	int point_num;
	SimOne_Trajectory_Point points[SO_MAX_TRAJECTORY_POINT_NUM];
	bool isReverse;
};

struct SimOne_Data_ESP_Control : public SimOne_Data
{
	int stopDistance;
	float velocityLimit;
	float steering;
	float steerTorque;
	float accel;
	float accelUpperLimit;
	float accelLowerLimit;
	float accelUpperComfLimit;
	float accelLowerComfLimit;
	bool standStill;
	bool driveOff;
	int brakeMode;
	int vlcShutdown;
	int gearMode;
};

// ----------------------------
// Vehicle Event Information data (SimOne Input)
// ----------------------------
#define SOSM_VEHICLE_EVENT_PREFIX "SOSM_VEHICLE_EVENT_"

enum ESimone_Vehicle_EventInfo_Type
{
	ESimone_Vehicle_EventInfo_Type_Forward_Collision_Warning = 0,		// 	front_crash_warning
	ESimone_Vehicle_EventInfo_Type_Backward_Collision_Warning = 1,	// 	back_crash_warning
	ESimone_Vehicle_EventInfo_Type_Left_Turn_Decision = 2,			// 	turn_left
	ESimone_Vehicle_EventInfo_Type_Left_Turn_Warning = 3,				// 	left_warning
	ESimone_Vehicle_EventInfo_Type_Right_Turn_Decision = 4,			// 	turn_right
	ESimone_Vehicle_EventInfo_Type_Right_Turn_Warning = 5,			// 	right_warning
	ESimone_Vehicle_EventInfo_Type_Forward_Straight_Decision = 6,		// 	straight_through
	ESimone_Vehicle_EventInfo_Type_Forward_Straight_Warning = 7,		// 	straight_warning
	ESimone_Vehicle_EventInfo_Type_Over_Speed_Warning = 8,			// 	overspeeding_warning
	ESimone_Vehicle_EventInfo_Type_Lane_Change_Decision = 9,			//  lane_change
	ESimone_Vehicle_EventInfo_Type_Lane_Change_Warning = 10,			// 	lane_change_warning
	ESimone_Vehicle_EventInfo_Type_Overtake_Decision = 11,			// 	overtake
	ESimone_Vehicle_EventInfo_Type_Emergency_Braking_Decision = 12,	// 	emergency_braking
	ESimone_Vehicle_EventInfo_Type_Accelerate_Decision = 13			// 	accelerate

};

struct SimOne_Data_Vehicle_EventInfo : public SimOne_Data
{
	ESimone_Vehicle_EventInfo_Type  type;
};

// ----------------------------
// Trajectory planning data (SimOne Input, for display) 
// ----------------------------
#define SOSM_TRAJECTORY_PREFIX "SOSM_TRAJECTORY_"
#define SOSM_TRAJECTORY_SIZE_MAX 100

struct SimOne_Data_Trajectory_Entry
{
	float posX; // Trajectory Position X on Opendrive (by meter)
	float posY; // Trajectory Position Y on Opendrive (by meter)
	float vel;  // Velocity (by meter/second)
};

struct SimOne_Data_Trajectory : public SimOne_Data
{
	int trajectorySize; // Trajectory size
	SimOne_Data_Trajectory_Entry trajectory[SOSM_TRAJECTORY_SIZE_MAX]; // Trajectory, 100 max
};

// ----------------------------
//  MianVehicle data (SimOne Output) 
// ----------------------------
#define SOSM_POSE_PREFIX "SOSM_POSE_"
#define SOSM_EXTRA_STATES_SIZE_MAX 256
struct SimOne_Data_Gps : public SimOne_Data
{
	float posX; // Position X on Opendrive (by meter)
	float posY; // Position Y on Opendrive (by meter)
	float posZ; // Position Z on Opendrive (by meter)
	float oriX; // Rotation X on Opendrive (by radian)
	float oriY; // Rotation Y on Opendrive (by radian)
	float oriZ; // Rotation Z on Opendrive (by radian)
	float velX; // MainVehicle Velocity X on Opendrive (by meter)
	float velY; // MainVehicle Velocity Y on Opendrive (by meter)
	float velZ; // MainVehicle Velocity Z on Opendrive (by meter)
	float throttle; //MainVehicle throttle
	float brake; //MainVehicle brake;
	float steering; //MainVehicle Wheel Steering angle (deg)
	int gear; // MainVehicle gear position
	float accelX; // MainVehicle Acceleration X on Opendrive (by meter)
	float accelY; // MainVehicle Acceleration Y on Opendrive (by meter)
	float accelZ; // MainVehicle Acceleration Z on Opendrive (by meter)
	float angVelX; // MainVehicle Angular Velocity X on Opendrive (by meter)
	float angVelY; // MainVehicle Angular Velocity Y on Opendrive (by meter)
	float angVelZ; // MainVehicle Angular Velocity Z on Opendrive (by meter)
	float wheelSpeedFL;  // Speed of front left wheel (by meter/sec)
	float wheelSpeedFR;  // Speed of front right wheel (by meter/sec)
	float wheelSpeedRL;  // Speed of rear left wheel (by meter/sec)
	float wheelSpeedRR;  // Speed of rear right wheel (by meter/sec)
	float engineRpm;// Speed of engine (by r/min)
	float odometer;	// odometer in meter.
	int extraStateSize;
	float extraStates[SOSM_EXTRA_STATES_SIZE_MAX];// vehicle states subscripted by MainVehicleExtraDataIndics message
};

enum ESimOne_Data_Vehicle_State
{
	ESimOne_Data_Vehicle_State_SO_M_SW,       // Steering wheel torque, unit: N.m
	ESimOne_Data_Vehicle_State_S0_Vx_SM,      // Sprung Mass CG Vx
	ESimOne_Data_Vehicle_State_S0_Vy_SM,      // Sprung Mass CG Vy
	ESimOne_Data_Vehicle_State_S0_Vz_SM,      // Sprung Mass CG Vz
	ESimOne_Data_Vehicle_State_SO_M_ENGOUT,   // Engine Output Torque
	ESimOne_Data_Vehicle_State_SO_My_DR_L1,      // Wheels Driving Torque
	ESimOne_Data_Vehicle_State_SO_My_DR_R1,
	ESimOne_Data_Vehicle_State_SO_My_DR_L2,
	ESimOne_Data_Vehicle_State_SO_My_DR_R2,
	ESimOne_Data_Vehicle_State_SO_My_DR_L3,
	ESimOne_Data_Vehicle_State_SO_My_DR_R3,

	ESimOne_Data_Vehicle_State_SO_F_Pedal,    // Brake Pedal Force
	ESimOne_Data_Vehicle_State_SO_Pbk_Con,    // BrakeMasterCylinder Pressure
	ESimOne_Data_Vehicle_State_SO_My_Bk_L3,   // Brake Torque at Left Rear Wheel
	ESimOne_Data_Vehicle_State_SO_My_Bk_R3,   // Brake Torque at Right Rear Wheel

	ESimOne_Data_Vehicle_State_SO_ClutchTr,   // Transmission clutch control

	ESimOne_Data_Vehicle_State_SO_X_L1,       // x coordinate, wheel center L1
	ESimOne_Data_Vehicle_State_SO_Y_L1,
	ESimOne_Data_Vehicle_State_SO_Z_L1,
	ESimOne_Data_Vehicle_State_SO_X_L2,
	ESimOne_Data_Vehicle_State_SO_Y_L2,
	ESimOne_Data_Vehicle_State_SO_Z_L2,
	ESimOne_Data_Vehicle_State_SO_X_R1,
	ESimOne_Data_Vehicle_State_SO_Y_R1,
	ESimOne_Data_Vehicle_State_SO_Z_R1,
	ESimOne_Data_Vehicle_State_SO_X_R2,
	ESimOne_Data_Vehicle_State_SO_Y_R2,
	ESimOne_Data_Vehicle_State_SO_Z_R2,
	ESimOne_Data_Vehicle_State_SO_X_L3,       // x coordinate, wheel center L3
	ESimOne_Data_Vehicle_State_SO_Y_L3,
	ESimOne_Data_Vehicle_State_SO_Z_L3,
	ESimOne_Data_Vehicle_State_SO_X_R3,
	ESimOne_Data_Vehicle_State_SO_Y_R3,
	ESimOne_Data_Vehicle_State_SO_Z_R3,

	ESimOne_Data_Vehicle_State_SO_Xctc_L1,      // x coordinate, center of tire contact L1
	ESimOne_Data_Vehicle_State_SO_Yctc_L1,      // y coordinate, center of tire contact L1
	ESimOne_Data_Vehicle_State_SO_Zctc_L1,      // z coordinate, center of tire contact L1
	ESimOne_Data_Vehicle_State_SO_Xctc_L2,
	ESimOne_Data_Vehicle_State_SO_Yctc_L2,
	ESimOne_Data_Vehicle_State_SO_Zctc_L2,
	ESimOne_Data_Vehicle_State_SO_Xctc_R1,
	ESimOne_Data_Vehicle_State_SO_Yctc_R1,
	ESimOne_Data_Vehicle_State_SO_Zctc_R1,
	ESimOne_Data_Vehicle_State_SO_Xctc_R2,
	ESimOne_Data_Vehicle_State_SO_Yctc_R2,
	ESimOne_Data_Vehicle_State_SO_Zctc_R2,

	ESimOne_Data_Vehicle_State_SO_AVy_L1,     // Wheel L1 spin    unit: rpm
	ESimOne_Data_Vehicle_State_SO_Kappa_L1,   // Longitudinal slip, tire L1   ratio, no unit
	ESimOne_Data_Vehicle_State_SO_Alpha_L1,   // Lateral slip angle, tire L1  unit: degree
	ESimOne_Data_Vehicle_State_SO_Fz_L1,      // Vertical force, tire L1   unit: N
	ESimOne_Data_Vehicle_State_SO_My_WC_L1,   // Tire My at wheel center L1   unit: N.m
	ESimOne_Data_Vehicle_State_SO_Fx_L1,      // Longitudinal force, tire L1   unit: N
	ESimOne_Data_Vehicle_State_SO_Fy_L1,      // lateral force, tire L1  unit: N
	ESimOne_Data_Vehicle_State_SO_Jnc_L1,     // Wheel L1 jounce (compression)   unit: mm
	ESimOne_Data_Vehicle_State_SO_JncR_L1,    // Wheel L1 jounce rate         unit: mm/s
	ESimOne_Data_Vehicle_State_SO_Mz_L1,      // Aligning moment, tire L1   unit: Nm

	ESimOne_Data_Vehicle_State_SO_AVy_L2,     //  Wheel L2 spin    unit: rpm
	ESimOne_Data_Vehicle_State_SO_Kappa_L2,   // Longitudinal slip, tire L2   ratio, no unit
	ESimOne_Data_Vehicle_State_SO_Alpha_L2,   // Lateral slip angle, tire L2  unit: rad
	ESimOne_Data_Vehicle_State_SO_Fz_L2,
	ESimOne_Data_Vehicle_State_SO_My_WC_L2,
	ESimOne_Data_Vehicle_State_SO_Fx_L2,       // Longitudinal force, tire L2
	ESimOne_Data_Vehicle_State_SO_Fy_L2,       // lateral force, tire L2
	ESimOne_Data_Vehicle_State_SO_Jnc_L2,      // Wheel L2 jounce (compression)  unit: cm
	ESimOne_Data_Vehicle_State_SO_JncR_L2,     // Wheel L2 jounce rate   unit: cm/s
	ESimOne_Data_Vehicle_State_SO_Mz_L2,       // Aligning moment, tire L2  unit: Nm

	ESimOne_Data_Vehicle_State_SO_AVy_R1,
	ESimOne_Data_Vehicle_State_SO_Kappa_R1,
	ESimOne_Data_Vehicle_State_SO_Alpha_R1,    // Lateral slip angle, tire R1  unit: degree
	ESimOne_Data_Vehicle_State_SO_Fz_R1,
	ESimOne_Data_Vehicle_State_SO_My_WC_R1,
	ESimOne_Data_Vehicle_State_SO_Fx_R1,       // Longitudinal force, tire R1
	ESimOne_Data_Vehicle_State_SO_Fy_R1,       // lateral force, tire R1
	ESimOne_Data_Vehicle_State_SO_Jnc_R1,      // Wheel R1 jounce (compression)
	ESimOne_Data_Vehicle_State_SO_JncR_R1,     // Wheel R1 jounce rate
	ESimOne_Data_Vehicle_State_SO_Mz_R1,       // Aligning moment, tire R1

	ESimOne_Data_Vehicle_State_SO_AVy_R2,
	ESimOne_Data_Vehicle_State_SO_Kappa_R2,
	ESimOne_Data_Vehicle_State_SO_Alpha_R2,    // Lateral slip angle, tire R2  unit: degree
	ESimOne_Data_Vehicle_State_SO_Fz_R2,
	ESimOne_Data_Vehicle_State_SO_My_WC_R2,
	ESimOne_Data_Vehicle_State_SO_Fx_R2,       // Longitudinal force, tire R2
	ESimOne_Data_Vehicle_State_SO_Fy_R2,       // lateral force, tire R2
	ESimOne_Data_Vehicle_State_SO_Jnc_R2,      // Wheel R2 jounce (compression)
	ESimOne_Data_Vehicle_State_SO_JncR_R2,     // Wheel R2 jounce rate
	ESimOne_Data_Vehicle_State_SO_Mz_R2,       // Aligning moment, tire R2

	ESimOne_Data_Vehicle_State_SO_AVy_L3,     // Wheel L3 spin    unit: rpm
	ESimOne_Data_Vehicle_State_SO_Kappa_L3,   // Longitudinal slip, tire L3   ratio, no unit
	ESimOne_Data_Vehicle_State_SO_Alpha_L3,   // Lateral slip angle, tire L3  unit: degree
	ESimOne_Data_Vehicle_State_SO_Fz_L3,      // Vertical force, tire L3   unit: N
	ESimOne_Data_Vehicle_State_SO_My_WC_L3,   // Tire My at wheel center L3   unit: N.m
	ESimOne_Data_Vehicle_State_SO_Fx_L3,      // Longitudinal force, tire L3   unit: N
	ESimOne_Data_Vehicle_State_SO_Fy_L3,      // lateral force, tire L3  unit: N
	ESimOne_Data_Vehicle_State_SO_Jnc_L3,     // Wheel L3 jounce (compression)   unit: mm
	ESimOne_Data_Vehicle_State_SO_JncR_L3,    // Wheel L3 jounce rate         unit: mm/s
	ESimOne_Data_Vehicle_State_SO_Mz_L3,      // Aligning moment, tire L3   unit: Nm

	ESimOne_Data_Vehicle_State_SO_AVy_R3,
	ESimOne_Data_Vehicle_State_SO_Kappa_R3,
	ESimOne_Data_Vehicle_State_SO_Alpha_R3,    // Lateral slip angle, tire R3  unit: degree
	ESimOne_Data_Vehicle_State_SO_Fz_R3,
	ESimOne_Data_Vehicle_State_SO_My_WC_R3,
	ESimOne_Data_Vehicle_State_SO_Fx_R3,       // Longitudinal force, tire R3
	ESimOne_Data_Vehicle_State_SO_Fy_R3,       // lateral force, tire R3
	ESimOne_Data_Vehicle_State_SO_Jnc_R3,      // Wheel R3 jounce (compression)
	ESimOne_Data_Vehicle_State_SO_JncR_R3,     // Wheel R3 jounce rate
	ESimOne_Data_Vehicle_State_SO_Mz_R3,       // Aligning moment, tire R3

	ESimOne_Data_Vehicle_State_SO_Steer_L3,
	ESimOne_Data_Vehicle_State_SO_Steer_R3,

	ESimOne_Data_Vehicle_State_SO_Steer_SW,   // Steering wheel angle  unit: deg
	ESimOne_Data_Vehicle_State_SO_TimePassed
};

#define SOSM_VEHICLE_EXTRA_STATE_MAX_SIZE 600
struct SimOne_Data_Vehicle_Extra
{
	int dataSize;
	float extra_states[SOSM_VEHICLE_EXTRA_STATE_MAX_SIZE];
};

// ----------------------------
// Obstacle GroundTruth data (SimOne Output) 
// ----------------------------
#define SOSM_OBSTACLE_PREFIX "SOSM_OBSTACLE_"
#define SOSM_OBSTACLE_SIZE_MAX 255

enum ESimOne_Obstacle_Type
{
	ESimOne_Obstacle_Type_Unknown = 0,
	ESimOne_Obstacle_Type_Pedestrian = 4,
	ESimOne_Obstacle_Type_Pole = 5,
	ESimOne_Obstacle_Type_Car = 6,
	ESimOne_Obstacle_Type_Static = 7,
	ESimOne_Obstacle_Type_Bicycle = 8,
	ESimOne_Obstacle_Type_Fence = 9,
	ESimOne_Obstacle_Type_RoadMark = 12,
	ESimOne_Obstacle_Type_TrafficSign = 13,
	ESimOne_Obstacle_Type_TrafficLight = 15,
	ESimOne_Obstacle_Type_Rider = 17,
	ESimOne_Obstacle_Type_Truck = 18,
	ESimOne_Obstacle_Type_Bus = 19,
	ESimOne_Obstacle_Type_Train = 20,
	ESimOne_Obstacle_Type_Motorcycle = 21,
	ESimOne_Obstacle_Type_Dynamic = 22,
	ESimOne_Obstacle_Type_GuardRail = 23,
	ESimOne_Obstacle_Type_SpeedLimitSign = 26,
	ESimOne_Obstacle_Type_BicycleStatic = 27,
	ESimOne_Obstacle_Type_RoadObstacle = 29
};

struct SimOne_Data_Obstacle_Entry
{
	int id; // Obstacle global unique ID
	int viewId; // Obstacle view ID in Sim-One observer.
	ESimOne_Obstacle_Type type; // Obstacle Type
	float theta; // [deprecated] Please use oriZ for obstacle heading angle instead
	float posX; // Obstacle Position X on Opendrive (by meter), this point is the centroid of the obstacle.
	float posY; // Obstacle Position Y on Opendrive (by meter), this point is the centroid of the obstacle.
	float posZ; // Obstacle Position Z on Opendrive (by meter), this point is the centroid of the obstacle.
	float oriX; // Obstacle Rotation X on Opendrive (by radian)
	float oriY; // Obstacle Rotation Y on Opendrive (by radian)
	float oriZ; // Obstacle Rotation Z on Opendrive (by radian)
	float velX; // Obstacle Velocity X on Opendrive (by meter)
	float velY; // Obstacle Velocity Y on Opendrive (by meter)
	float velZ; // Obstacle Velocity Z on Opendrive (by meter)
	float length; // Obstacle length
	float width; // Obstacle width
	float height; // Obstacle height
	float accelX; // Obstacle Acceleration X on Opendrive (by meter)
	float accelY; // Obstacle Acceleration Y on Opendrive (by meter)
	float accelZ; // Obstacle Acceleration Z on Opendrive (by meter)
};

struct SimOne_Data_Obstacle : public SimOne_Data
{
	int obstacleSize; // Obstacle size
	SimOne_Data_Obstacle_Entry obstacle[SOSM_OBSTACLE_SIZE_MAX]; // Obstacle, 255 max
};


struct SimOne_Data_CaseInfo
{
	char caseName[SOSM_CASENAME_LENGTH];
	char caseId[SOSM_CASEID_LENGT];
	char taskId[SOSM_TASKID_LENGT];
};
enum ESimOne_Case_Status
{
	ESimOne_Case_Status_Unknown = 0,
	ESimOne_Case_Status_Stop = 1,
	ESimOne_Case_Status_Running = 2,
	ESimOne_Case_Status_Pause = 3
};

#define SOSM_SIGNAL_LIGHTS_PREFIX "SOSM_SIGNAL_LIGHTS_"
enum ESimOne_Signal_Light
{
	ESimOne_Signal_Light_None = 0,
	ESimOne_Signal_Light_RightBlinker = 1,
	ESimOne_Signal_Light_LeftBlinker = (1 << 1),
	ESimOne_Signal_Light_DoubleFlash = (1 << 2),
	ESimOne_Signal_Light_BrakeLight = (1 << 3),
	ESimOne_Signal_Light_FrontLight = (1 << 4),
	ESimOne_Signal_Light_HighBeam = (1 << 5),
	ESimOne_Signal_Light_BackDrive = (1 << 6)
};
struct SimOne_Data_Signal_Lights : public SimOne_Data
{
	uint32_t signalLights = 0;
};

#define SOSM_ENVIRONMENT "SOSM_ENVIRONMENT"
struct SimOne_Data_Environment
{
	float timeOfDay = 1000;			// time of day [0, 2400]
	float heightAngle = 90;			//	height angle [0, 90]
	float directionalLight = 0.5f;	// light for sun or moon [0, 1]
	float ambientLight = 0.5f;		// ambient light [0, 1]
	float artificialLight = 0.5f;	// artificial light [0, 1]
	float cloudDensity = 0.2f;		// cloud density [0, 1]
	float fogDensity = 0.0f;		// fog density [0, 1]
	float rainDensity = 0.0f;		// rain density [0, 1]
	float snowDensity = 0.0f;		// snow density [0, 1]
	float groundHumidityLevel = 0.1f; // ground humidity level [0, 1]
	float groundDirtyLevel = 0.1f;	// ground dirty level [0, 1]
};

// ----------------------------
// Sensor Configuration API.
// ----------------------------

enum ESimOne_Node_Type
{
	ESimOne_Node_Type_Vehicle = 0,
	ESimOne_Node_Type_Camera = 1,
	ESimOne_Node_Type_LiDAR = 2,
	ESimOne_Node_Type_MMWRadar = 3,
	ESimOne_Node_Type_UltrasonicRadar = 4,
	ESimOne_Node_Type_AllUltrasonicRadar = 5,
	ESimOne_Node_Type_GNSSINS = 6,
	ESimOne_Node_Type_PerfectPerception = 7,
	ESimOne_Node_Type_V2X = 8,
	ESimOne_Node_Type_SensorFusion = 9
};

enum ESimOne_Sensor_Data_Type
{
	ESimOne_Sensor_Data_Type_ImageWithGroundTruth = 0,
	ESimOne_Sensor_Data_Type_PointCloudWithGroundTruth = 1,
	ESimOne_Sensor_Data_Type_RadarDetections = 2,
	ESimOne_Sensor_Data_Type_UltrasonicRadar = 3,
	ESimOne_Sensor_Data_Type_ObstacleDetection = 4,
	ESimOne_Sensor_Data_Type_GroundTruth = 5,
	ESimOne_Sensor_Data_Type_V2X = 6,
	ESimOne_Sensor_Data_Type_V2XNFS = 7

};

#define SENSOR_IDTYPE_MAX 64
struct SimOne_Data_SensorConfiguration
{
	int id;
	char mainVehicleId[SENSOR_IDTYPE_MAX];
	char sensorId[SENSOR_IDTYPE_MAX];
	char sensorType[SENSOR_IDTYPE_MAX];
	float x;
	float y;
	float z;
	float roll;
	float pitch;
	float yaw;
	int hz;
};

#define SOSM_SENSOR_CONFIGURATION_LABEL "SOSM_SENSOR_CONFIGURATION"
#define SOSM_SENSOR_CONFIGURATION_SIZE_MAX 100
struct SimOne_Data_SensorConfigurations
{
	int dataSize; // data size	
	SimOne_Data_SensorConfiguration data[SOSM_SENSOR_CONFIGURATION_SIZE_MAX];
};

enum ESimOne_Client_Type {
	ESimOne_Client_Type_None = 0,
	ESimOne_Client_Type_Web = 1,
	ESimOne_Client_Type_TrafficProvider = 2,
	ESimOne_Client_Type_VehicleDynamic = 3,
	ESimOne_Client_Type_BridgeIO = 4,
	ESimOne_Client_Type_SimOneDLL = 5,
	ESimOne_Client_Type_Observer = 6,
	ESimOne_Client_Type_Sensor = 7,
	ESimOne_Client_Type_Traffic = 8
};

// ----------------------------
// HDMap data
// ----------------------------

// ----------------------------
// Prediction data (SimOne Output) 
// ----------------------------
#define SOSM_PREDICTION_PREFIX "SOSM_PREDICTION_"
struct SimOne_Data_Traffic_Info
{
	int id;
	float x;
	float y;
	float speed;
	float orientation;
};

struct SimOne_Data_Position_Info : public SimOne_Data
{
	float mean_x;
	float mean_y;
	float var_x;
	float var_y;
	float covar_xy;
};

struct SimOne_Data_Prediction : public SimOne_Data
{
	std::map<int, SSD::SimVector<SimOne_Data_Position_Info>> ped_predictions;
	std::map<int, SSD::SimVector<SimOne_Data_Position_Info>> veh_predictions;
	float ped_delta_t;
	float veh_delta_t;
};
#define MAX_MAINVEHICLE_NUM 10
struct SimOne_Data_MainVehicle_Info
{
	int size;
	char id_list[MAX_MAINVEHICLE_NUM][MAX_MAINVEHICLE_NAME_LEN];
	char type_list[MAX_MAINVEHICLE_NUM][MAX_MAINVEHICLE_NAME_LEN];
};

struct SimOne_Data_MainVehicle_Status
{
	char mainVehicleId[MAX_MAINVEHICLE_NAME_LEN];
	int mainVehicleStatus;
};

// ----------------------------
// TrafficLight data (SimOne Output) 
// ----------------------------
#define SOSM_TRAFFICLIGHT_PREFIX "SOSM_TRAFFICLIGHT_"
#define SOSM_TRAFFICLIGHT_SIZE_MAX 100

enum ESimOne_TrafficLight_Status
{
	ESimOne_TrafficLight_Status_Invalid = 0,
	ESimOne_TrafficLight_Status_Red = 1,
	ESimOne_TrafficLight_Status_Green = 2,
	ESimOne_TrafficLight_Status_Yellow = 3,
	ESimOne_TrafficLight_Status_RedBlink = 4,
	ESimOne_TrafficLight_Status_GreenBlink = 5,
	ESimOne_TrafficLight_Status_YellowBlink = 6,
	ESimOne_TrafficLight_Status_Black = 7
};

struct SimOne_Data_TrafficLight
{
	bool isMainVehicleNextTrafficLight = false;
	int opendriveLightId = 0;
	int countDown = 0;
	ESimOne_TrafficLight_Status status = ESimOne_TrafficLight_Status::ESimOne_TrafficLight_Status_Invalid;
};

struct SimOne_Data_TrafficLights : public SimOne_Data
{
	int trafficlightNum = 0;	// Obstacle number
	SimOne_Data_TrafficLight trafficlights[SOSM_TRAFFICLIGHT_SIZE_MAX];	// trafficlights, 100 max
};

// ----------------------------
// SimOneDriver status data (SimOne Output) 
// ----------------------------
#define SOSM_DRIVER_PREFIX "SOSM_DRIVER_"

enum ESimOne_Driver_Status
{
	ESimOne_Driver_Status_Unknown = 0,
	ESimOne_Driver_Status_Controlling = 1,
	ESimOne_Driver_Status_Disabled = 2
};

struct SimOne_Data_Driver_Status : public SimOne_Data
{
	ESimOne_Driver_Status driverStatus;
};

// ----------------------------
// Vehicle control mode (SimOne Output) 
// ----------------------------
#define SOSM_CONTROLMODE_PREFIX "SOSM_CONTROLMODE_"

enum SimOne_Control_Mode
{
	ESimOne_Control_Mode_Unknown = 0,
	ESimOne_Control_Mode_Auto = 1,
	ESimOne_Control_Mode_Manual = 2
};

struct SimOne_Data_Control_Mode : public SimOne_Data
{
	SimOne_Control_Mode controlMode;
};

// ----------------------------
// Scenario event
// ----------------------------
#define ENABLE_SCENARIO_EVENT
#define SCENARIO_EVENT_PREFIX "SCENARIO_EVENT_"

struct SimOne_Data_ScenarioEvent_ReaderStatus
{
	int readerState = 0;
};

struct SimOne_Data_ScenarioEvent_WriterStatus
{
	int writeState = 0;
};

struct SimOne_Data_ScenarioEvent : public SimOne_Data_ScenarioEvent_WriterStatus
{
	char event[64];
	char data[64];
};
#pragma pack(pop)
